/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <memory>
#include <string>
#include <unordered_set>
#include <nlohmann/json.hpp>
#include "web_server.h"
#include "protocol.h"

namespace El {
namespace Restful {

/**
 * @brief WebSocket连接处理器类
 * 负责管理单个WebSocket连接的生命周期和消息处理
 */
class WebSocketConnection {
public:
    /**
     * @brief 构造函数
     * @param connection_id 连接唯一标识符
     */
    explicit WebSocketConnection(int64_t connection_id);
    ~WebSocketConnection() = default;

    // 禁止拷贝和赋值
    WebSocketConnection(const WebSocketConnection &) = delete;
    WebSocketConnection &operator=(const WebSocketConnection &) = delete;

    /**
     * @brief 处理WebSocket事件
     * @param event WebSocket事件
     * @return 处理结果（JSON字符串）
     */
    std::string ProcessEvent(std::shared_ptr<El::WebServer::WebSocketEvent> &event);

    /**
     * @brief 获取连接ID
     * @return 连接ID
     */
    int64_t GetConnectionId() const
    {
        return connection_id_;
    }

private:
    // 检查方法是否需要鉴权
    bool IsAuthRequired(const std::string &method) const;

    // 检查当前连接是否已鉴权
    bool IsAuthenticated() const;

    // 设置鉴权状态
    void SetAuthenticated(bool authenticated, const std::string &user_id = "");

    // 连接唯一标识符
    int64_t connection_id_;

    // 协议处理器
    std::shared_ptr<Protocol::IProtocol> protocol_;

    // 鉴权状态
    bool is_authenticated_ = false;

    // 已认证的用户ID
    std::string authenticated_user_id_;

    // 不需要鉴权的方法列表
    const std::unordered_set<std::string> non_auth_methods_ = {"auth.getChallenge", "auth.login"};
};

} // namespace Restful
} // namespace El